function webSocket(url) {
    if (!window.WebSocket) {
        console.log("web browser not support websocket！");
        return null;
    }
    this.init(url);
    this.on("ready",function(){
        this.socketReadyState=1;
        if(this.readyEmitList.length>0){
            for(var i=0;i<this.readyEmitList.length;i++){
                this.emit(this.readyEmitList[i]);
                // console.log("socketw connect is ready command:"+this.readyEmitList[i]);
            }
        }
        this.readyEmitList=new Array();

    });
    return this;
}
webSocket.prototype = {
    init: function(url) {
        this.initListeners();
        this.initSocket(url);
        this.bindSocketEvent();
    },

    initSocket: function(url) {
        this.url = url;
        this.socket = new WebSocket(url);//js对象
        return this;
    },

    initListeners: function() {
        this.listeners = {};
        return this;
    },

    bindSocketEvent: function() {
        var me = this;
        me.socket.onopen = function() {
            me.stopHeartBeat();
            me.startHeartBeat();
            me.trigger('ready');
            me.trigger('connect');
        }

        me.socket.onerror = function(e) {
            me.trigger('onerror', e);
            me.websocketClose();
        }
        me.callBack=function (data,me) {
            var length;
            if((length=data.indexOf("42"))!=0){
                return ;
            }
            data=data.substring(2,data.length);
            var array = JSON.parse(data);
            if(array.length!=2){
                return
            }
            //console.log(array[0]+array[1]);
            var topic=array[0];
            var msg=array[1];
            if(typeof  msg == "string" && msg.constructor == String){

            }else {
                msg = JSON.stringify(array[1]);
            }
            me.trigger(topic, msg);
        }
        me.socket.onmessage = function(e) {
            me.refreshServerTimer();
            if(e.data==3){
                return ;//心跳不处理
            }
            var data=isStringType(e.data,me);
            if(data==null){
                return ;
            }
            var length;
            if((length=data.indexOf("42"))!=0){
                return ;
            }
            data=data.substring(2,data.length);
            var array = JSON.parse(data);
            if(array.length!=2){
                return
            }
            //console.log(array[0]+array[1]);
            array[1]=isStringType(array[1]);
            var datamsg="42"+JSON.stringify(array);
            me.callBack(datamsg,me);

        }
        me.socket.onclose = function(e) {
            console.log("websocket is close");
            me.trigger('close', e);
            me.websocketClose();
            setTimeout(function() {
                me.websockertReConnect();
            },5000)
        }
        return this;
    },

    websockertReConnect: function() {
        console.log("websocket is reconnecting");
        this.socketReadyState=0;
        this.readyEmitList=new Array();
        this.initSocket(this.url).bindSocketEvent();
        this.trigger('reconnect');
    },

    isOffline: function() {
        return this.socket.readyState != WebSocket.OPEN;
    },

    on: function(evt, fn) {
        var me = this;
        if(me.listeners[evt] && me.listeners[evt].length) {
            if(me.listeners[evt].indexOf(fn) == -1){
                me.listeners[evt].push(fn);
            }
        }else {
            me.listeners[evt] = [fn];
        }
        return this;
    },

    off: function(evt) {
        var me = this;

        if(me.listeners[evt] && me.listeners[evt].length){
           delete me.listeners[evt];

        }
        return this;
    },

    emit: function(topic,msg) {
        var me = this;
        var sendMsg;
        if(!isEmpty(msg)) {
            sendMsg = "42[";
            sendMsg = sendMsg + "\"" + topic + "\"" + "," + "\"" + msg + "\"" + "]";
        }else{
            sendMsg=topic;
        }
        if(me.socketReadyState==0){
            //socketw connecting
            // console.log("socket connecting");
            me.readyEmitList.push(sendMsg);
            return ;
        }
        me.socket.send(sendMsg);
        return this;
    },

    trigger: function(evt) {
        var me = this;
        if(me.listeners[evt]) {
            var length = me.listeners[evt].length;
            for(var i=0; i<length; i++) {
                me.listeners[evt][i].apply(me, [].slice.call(arguments,1));
            }
        }
        return this;
    },
    currentTime:new Date().getTime()
    ,
    startHeartBeat: function() {
        var me = this;
        me.heartBeatTimer = setInterval(function() {
            //console.log("loca ping:"+me.currentTime);
            me.emit(2);//{ping:me.currentTime}
            me.currentTime=me.currentTime+5000;
        }, 5000);
    },

    stopHeartBeat: function() {
        clearInterval(this.heartBeatTimer);
    },

    //重新开始断线计时，20秒内没有收到任何正常消息或心跳就超时掉线
    refreshServerTimer: function() {
        var me = this;

        clearTimeout(me.serverHeartBeatTimer);
        me.serverHeartBeatTimer = setTimeout(function() {
            me.trigger("disconnect");
            me.websocketClose();
            setTimeout(function() {
                me.websockertReConnect();
            },5000)
        }, 20000)
    },

    clearAll: function() {
        var tmp = this.listeners['ready'];
        this.listeners = {};
        this.listeners['ready'] = tmp;
        return this;
    },

    websocketClose: function(options) {
        var me = this;
        clearTimeout(me.serverHeartBeatTimer);
        me.stopHeartBeat();
        me.socket.close();
        return this;
    },
    socketReadyState:0,
    readyEmitList:new Array()
}
